在上一篇文章中提到,到底 reconciler 的對象是誰呢?看起來超像對 component 的,但似乎不大一樣,在本篇會完整的解釋給你聽
我們一直說的 vDOM,其最小單位就是 ReactJS 的 JSX(或 createElement
...) 所生成出的物件(POJO),也就是 reconciler 的最小單位 --- Fiber。
如果把 JSX 也想成 XML tree 的話,
JSX <----> Fiber Tree <----> DOM Tree
這三種應該要互相 mapping 的,而 fiber 到 DOM(或其他 host env) 便是由昨天所說的 host config 所定義的。
在實踐上,host config 中有個 handler 叫
shouldSetTextContent
可以控制要不要繼續往下 render 子樹,還是當成 leaf 就結束了,所以可能會造成無法完整 mapping 的情形
(不過這太細節了,可以忽略)
reconciliation 是以整個 vDOM 的角度來看兩個新舊的 vDOM tree 要不要更新的機制。
而昨天寫出的 prepareUpdate
、 commitUpdate
這些 handler 是給 fiber 用的,用來判斷要不要更新其 mapping 到的 component。
而觸發 Update (ex. setState)到更新子樹的過程是建立在 vDOM tree 的遍歷,目前看起來是走 DFS 沒錯。
在出現 Fiber 之前, react 一次的 render 是無法中途暫停的,因此如果大量操作 DOM 常常會有掉幀的情形發生。因此 Fiber 因應而生。
Fiber 的出現是為了讓 ReactJS 更好地利用 Scheduling 做到讓 render 拆分,才不會阻塞渲染。
Fiber 和上一版 stack 的比較
https://claudiopro.github.io/react-fiber-vs-stack-demo/
另外,也可以藉由 priority 來排 render 的順序,或塞進不同的 callback:
requestAnimationFrame
requestIdleCallback
正因為 react 是有「根據 Function 來 render 的特性」,所以最好來實現控制 render 順序的方式就是使用 stack(這和許多 runtime 的設計相似 ex. v8 的 call stack)。
本節是參考自 https://github.com/acdlite/react-fiber-architecture
因為當時 scheduler 還算 WIP,所以內文也沒有著墨太多
明天有空的話,可以來研究看看這部分 (゚∀゚)
花了兩篇總算把 reconciler 搞清楚了
不過總結來說,React 的核心思想是利用聲明式的語法來簡單地操作 UI
因此從 JSX 到 DOM tree 的更新是完全封裝在 react 裡,不特別花時間去了解,平時真的不會碰到呢XD
前端工程師一起來種一棵後端技能樹吧!
想盡辦法當好一個Junior Backend Developer